﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using DoubleH.Utility;
using System.Collections;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
using Table = FCNS.Data.Table;
using System.Diagnostics;
using System.Xml.Linq;
using System.Xml;
using System.Windows.Markup;
using DoubleH.Utility.Configuration;
using System.Reflection;

namespace DoubleH.Utility.UC
{
    public class DataGridExt : DataGrid
    {
        public delegate void DeleteClick();
        public event DeleteClick OnDelete;

        ContextMenu contextMenuOnBody = new ContextMenu();
        ContextMenu contexMenuOnHeader = new ContextMenu();
        DataGridBoundColumn selectedDataGridBoundColumn = null;
        List<DataGridColumnHeaderBinding> columns = null;

        public DataGridExt()
        {
            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                return;

            ResourceDictionary newDictionary = new ResourceDictionary();
            newDictionary.Source = new Uri("Pack://application:,,,/DoubleH.Utility;Component/themes/Generic.xaml");
            this.Resources.MergedDictionaries.Add(newDictionary);

            this.CanUserDeleteRows = false;//这个是必须的

            InitMenu();
            InitEvent();
        }

        private void InitEvent()
        {
            contexMenuOnHeader.Opened += new RoutedEventHandler(contexMenuOnHeader_Opened);
        }

        void contexMenuOnHeader_Opened(object sender, RoutedEventArgs e)
        {
            DataGridColumnHeaderBinding item = GetColumnBinding();
            if (item == null)
                return;

            MenuItem mi = (MenuItem)contexMenuOnHeader.Items[0];
            mi.IsChecked = item.CanSearch;
        }

        #region 重绘
        protected override void OnLoadingRow(DataGridRowEventArgs e)
        {
            base.OnLoadingRow(e);
            int i= e.Row.GetIndex() + 1;
            e.Row.Header =i;
            if (lastRowBlod)
                e.Row.FontWeight = ((i == Items.Count) ? FontWeights.Bold : FontWeights.Normal);

            Table.AfterSaleServiceS ass = e.Row.Item as Table.AfterSaleServiceS;
            if (ass != null && ass.First)
                e.Row.Foreground = Brushes.Red;
        }

        protected override void OnMouseRightButtonUp(System.Windows.Input.MouseButtonEventArgs e)
        {
            base.OnMouseRightButtonUp(e);

            DependencyObject obj = e.OriginalSource as DependencyObject;

            while (obj != null && !(obj is DataGridColumnHeader))
                obj = VisualTreeHelper.GetParent(obj);

            DataGridColumnHeader header = obj as DataGridColumnHeader;
            if (header != null)
            {
                selectedDataGridBoundColumn = header.Column as DataGridBoundColumn;

                if (showHeaderMenu)
                    ContextMenu = contexMenuOnHeader;

                //MessageBox.Show(showHeaderMenu.ToString() + contexMenuOnHeader.Items.Count.ToString());
            }
            else
            {
                selectedDataGridBoundColumn = null;

                if (showBodyMenu)
                    ContextMenu = contextMenuOnBody;

                //MessageBox.Show(showBodyMenu.ToString() + contextMenuOnBody.Items.Count.ToString());
            }
        }

        protected override void OnSorting(DataGridSortingEventArgs eventArgs)
        {
            base.OnSorting(eventArgs);
            if(userParams==null)
                return;

            userParams.SortName = eventArgs.Column.SortMemberPath;
            userParams.SortDirection =(eventArgs.Column.SortDirection.HasValue? eventArgs.Column.SortDirection.Value:ListSortDirection.Descending);
        }
     
        //protected override void OnKeyUp(KeyEventArgs e)
        //{
        //    base.OnKeyUp(e);

        //    if (SelectionUnit == DataGridSelectionUnit.FullRow && e.Key == Key.Delete && OnDelete != null)
        //        OnDelete();
        //}
        #endregion

        #region 属性
        bool lastRowBlod = false;
        /// <summary>
        /// 底部行是否加粗显示
        /// </summary>
        public bool LastRowBlod
        {
            set { lastRowBlod = value; }
        }

        UserUIparams userParams = null;
        public UserUIparams UserParams
        {
            get { return userParams; }
            set
            {
                userParams = value;
                InitColumns(value.Items);
            }
        }

        bool showBodyMenu = false;
        /// <summary>
        /// 是否显示行右键菜单
        /// </summary>
        public bool ShowBodyMenu
        {
            get { return showBodyMenu; }
            set
            {
                showBodyMenu = value;
            }
        }

        bool showHeaderMenu = true;
        /// <summary>
        /// 是否显示列标题菜单
        /// </summary>
        public bool ShowHeaderMenu
        {
            get { return showHeaderMenu; }
            set { showHeaderMenu = value; }
        }
        /// <summary>
        /// 获取右键菜单
        /// </summary>
        public ContextMenu BodyMenu
        {
            get { return contextMenuOnBody; }
        }
        #endregion


        private void InitMenu()
        {
            MenuItem search = new MenuItem();
            search.IsCheckable = true;
            search.Header = "可搜索";
            search.Click += (ss, ee) =>
            {
                DataGridColumnHeaderBinding item = GetColumnBinding();
                if (item != null)
                    search.IsChecked = !item.CanSearch;
            };
            contexMenuOnHeader.Items.Add(search);
            contexMenuOnHeader.Items.Add(new Separator());

            MenuItem pailie = new MenuItem();
            pailie.Header = "内容布局";
            pailie.IsCheckable = false;
            contexMenuOnHeader.Items.Add(pailie);

            pailie.Items.Add(InitBuJuMenu("左对齐"));
            pailie.Items.Add(InitBuJuMenu("居中"));
            pailie.Items.Add(InitBuJuMenu("右对齐"));
            //pailie.Items.Add(InitBuJuMenu("顶部"));
            //pailie.Items.Add(InitBuJuMenu("中间"));
            //pailie.Items.Add(InitBuJuMenu("底部"));

            //body菜单
            MenuItem mi1 = new MenuItem();
            mi1.Header = "移除选中行";
            mi1.Click += (ss, ee) =>
            {
                if (OnDelete != null)
                    OnDelete();
            };

            contextMenuOnBody.Items.Add(mi1);
        }

        private MenuItem InitBuJuMenu(string header)
        {
            MenuItem pailie = new MenuItem();
            pailie.Header = header;
            pailie.IsCheckable = false;
            pailie.Click += (ss, ee) => { ColumnTextAlign(header); };
            return pailie;
        }

        private void ColumnTextAlign(string header)
        {
            if (selectedDataGridBoundColumn == null)
                return;

            DataGridColumnHeaderBinding item = GetColumnBinding();
            if (item == null)
                return;

            item.StyleKey = header;
            selectedDataGridBoundColumn.ElementStyle = Resources[header] as Style;

        }

        public void Init(UserUIparams userParams)
        {
            this.UserParams = userParams;
        }
        /// <summary>
        /// 初始化 DataGrid 的Columns
        /// </summary>
        /// <param name="binding"></param>
       private void InitColumns(List<DataGridColumnHeaderBinding> columns)
        {
            SaveDataGridColumnsWidthAndIndex();
            this.Columns.Clear();
            while (contexMenuOnHeader.Items.Count > 3)
                contexMenuOnHeader.Items.RemoveAt(3);

            Debug.Assert(columns != null);
            this.columns = columns;
            columns.Sort((l, r) =>
            {
                if (l.Index < r.Index)
                    return -1;
                else if (l.Index == r.Index)
                    return 0;
                else return 0;
            });
            foreach (DataGridColumnHeaderBinding item in columns)
            {
                MenuItem menu = new MenuItem() { Header = item.Header, IsChecked = item.Visible, Tag = item };
                contexMenuOnHeader.Items.Add(menu);
                menu.Click += (ss, ee) =>
                {
                    MenuItem m = (MenuItem)ss;
                    m.IsChecked = !m.IsChecked;
                    DataGridColumnHeaderBinding wu = (DataGridColumnHeaderBinding)(m.Tag);
                    wu.Visible = !wu.Visible;
                    if (!wu.Visible)
                        Columns.Remove((from f in Columns
                                        where
                                            ((Binding)((DataGridTextColumn)f).Binding).Path.Path == wu.BindingName
                                        select f).FirstOrDefault());
                    else
                        AddColumn(wu);
                };

                if (item.Visible)
                    AddColumn(item);
            }
        }

        private void AddColumn(DataGridColumnHeaderBinding item)
        {
            switch (item.ColumnType)
            {
                case "ProgressBar":
                     DataGridTemplateColumn gc_p = new DataGridTemplateColumn();
                     gc_p.Header = item.Header;
                     gc_p.Width = item.Width;

                     XNamespace ns_p = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
                     XElement xDataTemplate_p =
                        new XElement(ns_p + "DataTemplate", new XAttribute("xmlns", "http://schemas.microsoft.com/winfx/2006/xaml/presentation"),
 new XElement(ns_p + "ProgressBar", new XAttribute("Value", "{Binding " + item.BindingName + "}"), new XAttribute("Minimum", "0"),
      new XAttribute("Maximum", "1")));
                    //将内存中的XAML实例化成为DataTemplate对象，并赋值给
                    //ListBox的ItemTemplate属性，完成数据绑定
                     XmlReader xr_p = xDataTemplate_p.CreateReader();
                     DataTemplate dataTemplate_p = XamlReader.Load(xr_p) as DataTemplate;
                     gc_p.CellTemplate = dataTemplate_p;
                     Columns.Add(gc_p);
                     break;

                case "CheckBox":
                    DataGridCheckBoxColumn checkbox = new DataGridCheckBoxColumn();
                    checkbox.Width = item.Width;
                    //checkbox.ElementStyle = Resources[item.StyleKey] as Style;
                    checkbox.IsReadOnly = item.IsReadOnly;
                    checkbox.Header = item.Header;
                    checkbox.Binding = new Binding(item.BindingName);
                    Columns.Add(checkbox);
                    break;

                case "Image":
                    DataGridTemplateColumn gc_i = new DataGridTemplateColumn();
                    gc_i.Header = item.Header;
                    gc_i.Width = item.Width;

                    XNamespace ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
                    XElement xDataTemplate =
                        new XElement(ns + "DataTemplate", new XAttribute("xmlns", "http://schemas.microsoft.com/winfx/2006/xaml/presentation"),
 new XElement(ns + "Image", new XAttribute("Source", "{Binding " + item.BindingName + "}"), new XAttribute("Stretch", "Fill"), new XAttribute("Width", gc_i.Width), new XAttribute("Height", gc_i.Width)));

                    //将内存中的XAML实例化成为DataTemplate对象，并赋值给
                    //ListBox的ItemTemplate属性，完成数据绑定
                    XmlReader xr = xDataTemplate.CreateReader();
                    DataTemplate dataTemplate = XamlReader.Load(xr) as DataTemplate;
                    gc_i.CellTemplate = dataTemplate;
                    Columns.Add(gc_i);
                    break;


                case "Hyperlink":
                    DataGridHyperlinkColumn gc2 = new DataGridHyperlinkColumn();
                    gc2.Width = item.Width;
                    gc2.ElementStyle = Resources[item.StyleKey] as Style;
                    gc2.IsReadOnly = item.IsReadOnly;
                    gc2.Header = item.Header;
                    gc2.ContentBinding = new Binding(item.ContentBindingName);
                    Columns.Add(gc2);
                    break;


                default:
                    DataGridTextColumn gc = new DataGridTextColumn();
                    gc.Width = item.Width;
                    gc.ElementStyle = Resources[item.StyleKey] as Style;
                    gc.IsReadOnly = item.IsReadOnly;
                    gc.Header = item.Header;
                    gc.Binding = new Binding(item.BindingName);
                    Columns.Add(gc);
                    break;
            }

            item.Index = Columns.Count;

        }

        private void SaveDataGridColumnsWidthAndIndex()
        {
            if (columns == null || DoubleHConfig.UserConfig == null)
                return;

            for (int i = 0; i < Columns.Count; i++)
            {
                DataGridBoundColumn db = Columns[i] as DataGridBoundColumn;
                if (db == null||db.Binding==null)
                    continue;

                string bindingName = ((Binding)db.Binding).Path.Path;
                DataGridColumnHeaderBinding item = columns.Find(f => { return f.BindingName == bindingName; });
                DataGridColumn column = Columns[i];
                item.Width = column.ActualWidth;
                item.Index = column.DisplayIndex;
            }
        }

        public DataGridColumn GetColumn(string bindingName)
        {
          return Columns.FirstOrDefault(f => ((Binding)((DataGridBoundColumn)f).Binding).Path.Path == bindingName);
        }

        private DataGridColumnHeaderBinding GetColumnBinding()
        {
            if (selectedDataGridBoundColumn == null)
                return null;

            DataGridColumnHeaderBinding item =columns.Find(f => { return f.BindingName == ((Binding)selectedDataGridBoundColumn.Binding).Path.Path; });
            return item;
        }
    }
}